#include <string.h>
#include <stdlib.h>
#include <Includes.h>
#include <DRV_Event.h>
//#include <DRV_Bc28.h>
//#include <DRV_Bc28_Event.h>
#include <DRV_EC600S.h>
#include <DRV_EC600S_Event.h>
#include <OPP_Debug.h>

#define MAX(a,b)  a>b?a:b
ST_EVENT g_astEvent[EN_DEV_TYPE_MAX][EC600S_MAX_EVENT]=
{
    EC600S_EVENT_LIST
};

/* ============================================================
func name   :  initEvent
discription :  init event

param       :
return      :  0
Revision    :
=============================================================== */
int initEvent()
{
	int i = 0,j=0;
    for(i=0;i<EN_DEV_TYPE_MAX;i++)
    {
        for(j=0;j<ITEMS_OF(g_astEvent[i]);j++)
        {
    		MUTEX_CREATE(g_astEvent[i][j].mutex);
    		g_astEvent[i][j].sem = xSemaphoreCreateBinary();
    		if(NULL == g_astEvent[i][j].sem){
    			//printf("initEvent OS_SEMAPHORE_CREATE %d error\r\n", i);
    		}
    	}
    }
	return 0;
}

/* ============================================================
func name   :  recvEvent
discription :  receive special event

param       :  input para: event: event type, timeout: wait time
		      output para: argc: para number, argv: parameter,
return      :  0:success
Revision    :
=============================================================== */
int RecvEvent(EN_DEV_TYPE type, int event, int *argc, char *argv[], int timeout)
{
	int i;
	int ret = 0;

	while(1){
		BaseType_t r = OS_SEMAPHORE_TAKE(g_astEvent[type][event].sem,timeout);
		if (r == pdFALSE){
			return -1;
		}
		MUTEX_LOCK(g_astEvent[type][event].mutex,MUTEX_WAIT_ALWAYS);
		if(g_astEvent[type][event].state == OVER_STATE){
			*argc = g_astEvent[type][event].rspArgc;
			for(i=0;i<g_astEvent[type][event].rspArgc;i++){
				argv[i] = g_astEvent[type][event].rspArgv[i];
			}
			MUTEX_UNLOCK(g_astEvent[type][event].mutex);
			return g_astEvent[type][event].retCode;
		}
		MUTEX_UNLOCK(g_astEvent[type][event].mutex);
	}
	return ret;
}

/* ============================================================
func name   :  sendEvent
discription :  send event to event process

param       :  event: event type, state: event state, argc: para number, argv: parameter
return      :  0:success
Revision    :
=============================================================== */
int SendEvent(EN_DEV_TYPE type, int event, int state, int argc, char *argv[])
{
	int i = 0;

	MUTEX_LOCK(g_astEvent[type][event].mutex,MUTEX_WAIT_ALWAYS);
    g_astEvent[type][event].reqArgc = argc;
	for(i=0;i<argc;i++){
		g_astEvent[type][event].reqArgv[i] = argv[i];
	}
	g_astEvent[type][event].state = state;
	MUTEX_UNLOCK(g_astEvent[type][event].mutex);

	return 0;
}

int DevEventProc(EN_DEV_TYPE type)
{
    int i;
    ST_EVENT *pEvent;

    for(i=0;i<ITEMS_OF(g_astEvent[type]);i++)
    {
        MUTEX_LOCK(g_astEvent[type][i].mutex,MUTEX_WAIT_ALWAYS);
        pEvent=&g_astEvent[type][i];
        if(RISE_STATE == pEvent->state)
        {
            if(pEvent->evfunc!=NULL)
                pEvent->evfunc(pEvent->reqArgc,pEvent->reqArgv,&pEvent->retCode,&pEvent->rspArgc,pEvent->rspArgv);
            ARGC_FREE(pEvent->reqArgc,pEvent->reqArgv);
            pEvent->state = OVER_STATE;
            OS_SEMAPHORE_GIVE(pEvent->sem);
        }
        MUTEX_UNLOCK(g_astEvent[type][i].mutex);
    }
    return 0;
}

/**
@brief EC600查询事件对外接口函数
@param
	- event 事件类型
	- sargc 查询事件参数个数
	- sargv 查询事件参数内容，要求内容为字符串格式
	- rargc 接收事件参数个数
    - rargv 接收事件参数内容，要求内容为字符串格式
    - timeout 超时时间
@return none
**/
int Ec600sDoEvent(int event,int sargc,char *sargv[],int *rargc,char *rargv[],int timeout)
{
	int ret;
    int i;
	char *sArgv[MAX_ARGC];
	char *rArgv[MAX_ARGC];
	int sArgc = sargc, rArgc = 0;

    for(i=0;i<sArgc;i++)
    {
        sArgv[i]=(char *)malloc(strlen(sargv[i])+1);
        if(sArgv[i]==NULL)
        {
            return 1;
        }
        strcpy(sArgv[i],sargv[i]);
    }

	ret = SendEvent(EN_DEV_TYPE_EC600S,event,RISE_STATE,sArgc,sArgv);
	ret = RecvEvent(EN_DEV_TYPE_EC600S,event,&rArgc,rArgv,timeout);
	if(0 != ret){
		ARGC_FREE(rArgc,rArgv);
        return 10+ret;
	}
    for(i=0;i<rArgc;i++)
    {
        strcpy(rargv[i],rArgv[i]);
    }
    *rargc=rArgc;
    ARGC_FREE(rArgc,rArgv);
    return 0;
}


